package com.yuedou.api.controller.product;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.lock.LockInfo;
import com.baomidou.lock.LockTemplate;
import com.baomidou.lock.executor.RedissonLockExecutor;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yuedou.api.constant.ResponseCode;
import com.yuedou.api.controller.platform.BaseController;
import com.yuedou.api.entity.mall.MallGroupOpenDetail;
import com.yuedou.api.entity.mer.Mer;
import com.yuedou.api.entity.platform.*;
import com.yuedou.api.entity.product.*;
import com.yuedou.api.entity.wxmsg.MsgTempData;
import com.yuedou.api.entity.wxmsg.WxMsgTemplate;
import com.yuedou.api.entity.wxmsg.WxTemplate;
import com.yuedou.api.entity.wxuser.*;
import com.yuedou.api.pay.nongshang.NSHUtils;
import com.yuedou.api.pay.utils.RSA;
import com.yuedou.api.pay.wxpay.WXPayCommonUtil;
import com.yuedou.api.pay.wxpay.WxAppPay;
import com.yuedou.api.service.mer.MerService;
import com.yuedou.api.service.platfom.*;
import com.yuedou.api.service.product.*;
import com.yuedou.api.service.wxuser.*;

import com.vdurmont.emoji.EmojiParser;
import com.yuedou.api.util.*;
import com.yuedou.api.websocket.WebSocketServer;
import org.jdom2.JDOMException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.*;

/**
 *@Author: ZhouWei
 *@Description:  订单列表
 *@Date 2025-01-17
 */
@Component
@RestController
@RequestMapping("/pay")//url:模块/资源/{}/细分
public class PayController extends BaseController {
    @Resource
    private ProductOrderService productOrderService;
    @Resource
    private UserService userService;
    @Resource
    private UserMpService userMpService;
    @Resource
    private ProductService productService;
    @Resource
    private WxTemplateService wxTemplateService;
    @Resource
    private ProductOrderRelationService orderRelationService;
    @Resource
    private MerService merService;
    @Resource
    private SplitAccountService splitAccountService;
    @Resource
    private SmsTemplateService smsTemplateService;
    @Resource
    private WxPayTransactionService payTransactionService;
    @Resource
    private PlatformPayService platformPayService;
    @Resource
    private UserAddressService userAddressService;
    @Resource
    protected RedisTemplate<String, Object> redisTemplate;

    @Value("${web.appid}")
    private String appid;

    @Value("${web.nsh_notify_url}")
    private String nsh_notify_url;

    @Resource
    private LockTemplate lockTemplate;

    /**
     * 调起退款(发起退款操作)
     * @return
     */
    @PostMapping(value = "/requestRefund")
    public JSONObject requestRefund(@RequestBody String requestParam, HttpServletRequest request){
        JSONObject ret = null;
        try{
            if(StrUtil.isEmpty(requestParam)){
                return Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL,"参数异常"),true,true);
            }
            JSONObject jsonRequest = JSONUtil.parseObj(requestParam);
            int user_id = jsonRequest.containsKey("user_id") ? jsonRequest.getInt("user_id") : 0;
            long order_id = jsonRequest.containsKey("order_id") ? jsonRequest.getInt("order_id") : 0L;
            String reason = jsonRequest.containsKey("reason") ? jsonRequest.getStr("reason") : "";

            boolean blIsMineOrder = false;
            User user = userService.findById(user_id);
            if(user == null){
                return Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL,"该用户不存在"),true,true);
            }


            return Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL,"请联系客服退款"),true,true);
        }catch (Exception e){
            e.printStackTrace();
        }
        return ret;
    }

    /**
     * 微信小程序调起支付
     * @return
     */
    @PostMapping(value = "/requestPay")
    public JSONObject requestPay(@RequestBody String requestParam, HttpServletRequest request){
        JSONObject ret = null;
        if(StrUtil.isEmpty(requestParam)){
            return Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL,"参数异常"),true,true);
        }
        JSONObject jsonRequest = JSONUtil.parseObj(requestParam);
        int user_id = jsonRequest.containsKey("user_id") ? jsonRequest.getInt("user_id") : 0;
        long order_id = jsonRequest.containsKey("order_id") ? jsonRequest.getInt("order_id") : 0L;


        LockInfo lockInfo = lockTemplate.lock(order_id + "_requestPay", 30000L, 5000L, RedissonLockExecutor.class);
        if (lockInfo == null) {
            return Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL,"业务处理中,请稍后再试"),true,true);
        }

        try{
            String subject = jsonRequest.containsKey("subject") ? jsonRequest.getStr("subject") : "";
            String remark = jsonRequest.containsKey("remark") ? jsonRequest.getStr("remark") : null;

            int address_id = jsonRequest.containsKey("address_id") ? jsonRequest.getInt("address_id") : 0;

            String orderNo = "";
            boolean blIsMineOrder = false;


            User user = userService.findById(user_id);
            if(user == null){
                return Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL,"该用户不存在"),true,true);
            }



            PlatformPay platformPay = platformPayService.getDefaultAccount();
            ProductOrder orders = productOrderService.findById(order_id);
            if(orders != null){
                int orderUserId = orders.getUserId() ;

                if(orderUserId == user_id){
                    orderNo = orders.getOutTradeNo();
                    blIsMineOrder = true;
                }else{
                    blIsMineOrder = false;
                }

                if(orders.getOrderType() == 7){
                    UserAddress userAddress = userAddressService.findById(address_id);
                    if(userAddress == null){
                        return Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL, "请选择收货地址"), true, true);
                    }
                    orders.setUserAddress(userAddress.getAddress());
                    orders.setRealName(userAddress.getReceiverName());
                    orders.setUserPhone(userAddress.getPhoneNum());

                    Mer mer = merService.findById(orders.getMerId());
                    if(mer!= null){
                        boolean blIsInPoly = merService.isInPoly(mer, userAddress);
                        if(!blIsInPoly){
                            return Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL, "不在配送范围内，不能购买"), true, true);
                        }
                    }
                }

                if(orders.getStatus() == 0 || orders.getStatus() == 1){//如果是 再次提交支付的话，订单号要生成新的
                    orderNo = OrderUtil.getOrderNoByTimespan();
                    if(orders.getPayType() == 1) {
                        orderNo = OrderUtil.getOrderNoByTimespan(platformPay.getSysCode());
                    }
                    orders.setOutTradeNo(orderNo);
                }else if(orders.getStatus() == 2 || orders.getStatus() == 3 || orders.getStatus() == 4){
                    /**
                     * 订单状态 0 - 未支付   1 - 支付中  2 - 已支付（待核销）  3 - 已核销  4 - 已评价
                     * 5 - 订单取消  6 - 发起退货  7 - 同意退货  8 - 退货完成  9 - 拒绝退货  10 - 团购成功 11 - 团购失败
                     */
                    return Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL,"订单已支付"),true,true);
                } else if(orders.getStatus() == 5){
                    return Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL,"订单已取消"),true,true);
                }
                else{
                    return Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL,"当前状态不能发起支付"),true,true);
                }
                if(StrUtil.isNotEmpty(remark)){
                    orders.setRemark(remark);
                }
            }

            if(blIsMineOrder){
                if(orders.getPayPrice().doubleValue() > 0) {
                    String retRequest = platformPayService.appletOrder(orderNo, orders.getPayPrice(), subject, appid,user.getOpenId(), "NORMAL", nsh_notify_url, platformPay);
                    System.out.println("PayController requestPay 调起支付: " + retRequest);
                    JSONObject jsonObject = JSONUtil.parseObj(retRequest);
                    if (jsonObject != null) {
                        String errCode = jsonObject.getStr("errCode");
                        String errMsg = jsonObject.getStr("errMsg");
                        if (errCode.equals("SUCCESS")) {
                            JSONObject retData = jsonObject.getJSONObject("miniPayRequest");
                            retData.set("result_code", "SUCCESS");
                            ret = Tools.getJson(new GsonResultBean<>(ResponseCode.OK, "请求成功", retData.toString()), true, false);
                            orders.setStatus(1);//支付中
                            productOrderService.updateById(orders);
                        } else {
                            ret = Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL, errMsg), true, true);
                        }
                    }
                }else{
                    JSONObject retData = new JSONObject();
                    retData.set("result_code", "NOTNEEDPAY");
                    ret = Tools.getJson(new GsonResultBean<>(ResponseCode.OK, "请求成功"), true, false);
                    orders.setStatus(2);//无需支付的情况，抵扣完了
                    productOrderService.buyNormalUpdate(orders,user);

                }

            }else{//当前订单不属于您
                ret = Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL,"当前订单不属于您"),true,true);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //释放锁
            lockTemplate.releaseLock(lockInfo);
        }
        return ret;
    }

    /**
     *  线下支付调起支付
     * @return
     */
    @PostMapping(value = "/requestPayOffline")
    public JSONObject requestPayOffline(@RequestBody String requestParam, HttpServletRequest request){
        JSONObject ret = null;
        try{
            if(StrUtil.isEmpty(requestParam)){
                return Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL,"参数异常"),true,true);
            }
            JSONObject jsonRequest = JSONUtil.parseObj(requestParam);
            int user_id = jsonRequest.containsKey("user_id") ? jsonRequest.getInt("user_id") : 0;
            long order_id = jsonRequest.containsKey("order_id") ? jsonRequest.getInt("order_id") : 0L;
            String subject = jsonRequest.containsKey("subject") ? jsonRequest.getStr("subject") : "";
            String remark = jsonRequest.containsKey("remark") ? jsonRequest.getStr("remark") : "";

            boolean blIsMineOrder = false;
            User user = userService.findById(user_id);
            if(user == null){
                return Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL,"该用户不存在"),true,true);
            }

            PlatformPay platformPay = platformPayService.getDefaultAccount();
            ProductOrder orders = productOrderService.findById(order_id);
            if(orders != null){
                orders.setRemark(remark);
                int orderUserId = orders.getUserId();
                if(orderUserId == user_id){
                    blIsMineOrder = true;
                }


                String orderNo = "";
                if(orders.getStatus() == 1){//如果是 再次提交支付的话，订单号要生成新的
                    orderNo = OrderUtil.getOrderNoByTimespan();
                    if(orders.getPayType() == 1) {
                        orderNo = OrderUtil.getOrderNoByTimespan(platformPay.getSysCode());
                    }
                    orders.setOutTradeNo(orderNo);
                }else if(orders.getStatus() >= 2){
                    return Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL,"当前状态不能发起支付"),true,true);
                }

                if(blIsMineOrder){
                    String retRequest = platformPayService.appletOrder(orders.getOutTradeNo(), orders.getPayPrice(),subject,appid,user.getOpenId(),"OFFLINE",nsh_notify_url,platformPay);
                    System.out.println("requestPayOffline 线下支付调起支付: " + retRequest);
                    JSONObject jsonObject = JSONUtil.parseObj(retRequest);
                    if(jsonObject!=null){
                        String errCode = jsonObject.getStr("errCode");
                        String errMsg = jsonObject.getStr("errMsg");
                        if(errCode.equals("SUCCESS")){
                            JSONObject retData = jsonObject.getJSONObject("miniPayRequest");
                            retData.set("result_code","SUCCESS");
                            ret = Tools.getJson(new GsonResultBean<>(ResponseCode.OK,"请求成功",retData.toString()),true,false);
                            orders.setStatus(1);//支付中
                            productOrderService.updateById(orders);
                        }else{
                            ret = Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL,errMsg),true,true);
                        }
                    }
                }else{//当前订单不属于您
                    ret = Tools.getJson(new GsonResultBean<>(ResponseCode.FAIL,"当前订单不属于您"),true,true);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return ret;
    }


    /**
     *   农商行 代付接口 支付成功回调处理
     * @param params
     * @return
     * @throws IOException
     */
    @PostMapping(value = "/nsh_dai_pay_notify")
    public String nshDaiPayNotify(@RequestParam Map<String, String> params, HttpServletRequest request) throws IOException {
        System.out.println("农商行 代付接口 结果回调： " + params);
        int ret = 0;
        JSONObject jsonObject = new JSONObject(params);
        if(jsonObject!=null){

            return "success";
        }
        // 处理业务完毕
        // ------------------------------
        return "fail";
    }

    /**
     *   农商行 支付成功回调处理
     * @param params
     * @return
     * @throws IOException
     */
    @PostMapping(value = "/nsh_notify")
    public String nshPayNotify(@RequestParam Map<String, String> params,HttpServletRequest request) throws IOException {
        System.out.println("农商行 默认支付 支付回调： " + params);
        int ret = 0;
        JSONObject jsonObject = new JSONObject(params);
        if(jsonObject!=null){
            //TRADE_SUCCESS
            String status = jsonObject.getStr("status");
            String attach = jsonObject.getStr("attachedData");
            String orderNo = jsonObject.getStr("merOrderId");

            PlatformPay platformPay = platformPayService.getDefaultAccount();
            boolean blIsValidate = false;
            try {
                blIsValidate = NSHUtils.validateSignNSh(params,platformPay.getApiKey());
            } catch (Exception e) {
                e.printStackTrace();
            }
            if(blIsValidate){
                //支付成功的推送
                if(status.equals("TRADE_SUCCESS")){
                    String result_code = status;
                    System.out.println("附加信息: " + attach);
                    try {
                        if(attach.equals("NORMAL")){//普通商品订单
                            ret = pay_success_product(params,result_code,2);//逻辑处理
                        }
                        if(ret > 0){
                            return "success";
                        }else{
                            return "fail";
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                //退款 操作
                else if(status.equals("TRADE_REFUND")){
                    //商品退款回调
                    ret = refund_success_product(params,2);
                    if(ret > 0){
                        return "success";
                    }else{
                        return "fail";
                    }
                }
            }else{
                System.out.println("验签失败： 订单号：" + orderNo);
                return "fail";
            }
        }
        // 处理业务完毕
        // ------------------------------
        return "fail";
    }

    /**
     *   农商行 支付成功回调处理 (二维码模式)
     * @param params
     * @return
     * @throws IOException
     */
    @PostMapping(value = "/nsh_notify_qr")
    public String nshPayQrNotify(@RequestParam Map<String, String> params,HttpServletRequest request) throws IOException {
        System.out.println("农商行 默认支付 二维码模式 支付回调： " + params);
        int ret = 0;
        JSONObject jsonObject = new JSONObject(params);
        if(jsonObject!=null){
            //TRADE_SUCCESS
            String status = jsonObject.getStr("billStatus");
            String attach = jsonObject.getStr("attachedData");
            String orderNo = jsonObject.getStr("billNo");//订单号

            PlatformPay platformPay = platformPayService.getDefaultAccount();
            boolean blIsValidate = false;
            try {
                blIsValidate = NSHUtils.validateSignNSh(params,platformPay.getApiKey());
            } catch (Exception e) {
                e.printStackTrace();
            }
            if(blIsValidate){
                //支付成功的推送  已支付
                if(status.equals("PAID")){
                    String result_code = status;
                    System.out.println("附加信息: " + attach);
                    try {
                        if(attach.equals("NORMAL")){//普通商品订单
                            ret = pay_success_product(params,result_code,2);//逻辑处理
                        }
                        if(ret > 0){
                            return "success";
                        }else{
                            return "fail";
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                //退款 操作
                else if(status.equals("REFUND")){
                    //商品退款回调
                    ret = refund_success_product(params,2);
                    if(ret > 0){
                        return "success";
                    }else{
                        return "fail";
                    }
                }
            }else{
                System.out.println("验签失败： 订单号：" + orderNo);
                return "fail";
            }
        }
        // 处理业务完毕
        // ------------------------------
        return "fail";
    }

    /**
     * 商品订单的   成功之后的 业务处理
     * @param params
     * @param trade_status
     * @param payType
     * @return
     */
    @SuppressWarnings("unchecked")
    private int pay_success_product(Map<String, String> params,String trade_status,int payType){
        String out_trade_no = "";// 本平台  商户订单号
        if(params.containsKey("merOrderId")){
            out_trade_no = params.get("merOrderId");// 本平台  商户订单号
        } else if(params.containsKey("out_trade_no")){
            out_trade_no = params.get("out_trade_no");// 本平台  商户订单号
        }
        int ret = 0;
        try{
            QueryWrapper<ProductOrder> qw = new QueryWrapper<>();
            qw.eq("out_trade_no",out_trade_no).or().eq("order_no",out_trade_no);
            ProductOrder order = productOrderService.getOne(qw);
            if(order != null){
                User user = userService.findById(order.getUserId());
                if(order.getStatus() == 0 || order.getStatus() == 1 || order.getStatus() == 5) {//支付中的 状态 才往下执行
                    String total_amount = "";//  订单金额
                    String trade_no = "";//  订单号
                    double total_amount_double = 0;
                    String payTime = "";
                    if (trade_status.equals("SUCCESS") || trade_status.equals("TRADE_SUCCESS")) {
                        if (payType == 0) {//支付宝支付参数
                            total_amount = params.get("total_amount");
                            trade_no = params.get("trade_no");//支付宝支付订单号
                            total_amount_double = Double.valueOf(total_amount);
                        } else if (payType == 1) {//微信支付参数
                            total_amount = params.get("total_fee");
                            trade_no = params.get("transaction_id");//微信支付订单号
                            total_amount_double = Double.valueOf(total_amount) / 100;
                            payTime = params.get("time_end");
                        } else if (payType == 2) {// 农商行 支付参数
                            total_amount = params.get("totalAmount");
                            trade_no = params.get("targetOrderId");//微信支付订单号
                            total_amount_double = Double.valueOf(total_amount) / 100;
                            payTime = params.get("payTime");
                        }

                        //订单状态 0 - 未支付   1 - 支付中  2 - 已支付（待核销）  3 - 已核销
                        // 4 - 已评价  5 - 订单取消  6 - 发起退货  7 - 同意退货  8 - 退货完成  9 - 拒绝退货
                        order.setStatus(2);
                        order.setTransactionId(trade_no);
                        order.setPayPrice(new BigDecimal(total_amount_double));
                        order.setPayTime(new Date());
                        ret = productOrderService.buyNormalUpdate(order,user);
                        if(ret > 0){
                            //支付成功通知
                            sendWxMsg(user,order,7);
                            //String merName, String phoneNum, String productName
                            if(order.getOrderType() == 0 || order.getOrderType() == 4){
                                try{
                                    Product product = productService.getProductByOrderId(order.getId());
                                    if(product!=null){
                                        Mer mer = merService.findById(order.getMerId());
                                        if(mer != null){
                                            smsTemplateService.sendSmsByProductOrder(mer.getShopName(),mer.getTelphone(), product.getStoreName());
                                        }
                                    }
                                }catch (Exception e){
                                    e.printStackTrace();
                                }
                            }
                        }

                        // 添加 微信支付的 动账记录
                        WxPayTransaction transaction = new WxPayTransaction();
//                        transaction.setEstateName(order.getEstateName());
                        transaction.setPayType(payType);// 0 -微信支付
                        transaction.setTransactionId(trade_no);
                        transaction.setUserId(user.getId());
                        transaction.setFeeType("product");
                        transaction.setTotalMoney(new BigDecimal(total_amount_double));
                        transaction.setOutTradeNo(out_trade_no);
                        if(StrUtil.isNotEmpty(user.getNickName())){
                            transaction.setNickName(EmojiParser.parseToAliases(user.getNickName()));
                        }
                        transaction.setCreateTime(new Date());
                        transaction.setInOrOut(1);//动账  0 - 出账 1 - 进账
                        transaction.setRemark("购买商品/服务");
                        transaction.setPayPlatformId(order.getPayPlatformId());
                        payTransactionService.save(transaction);
                        System.out.println("=====支付成功====");
                        logger.info("普通商品订单号：" + out_trade_no + "支付成功");
                    }
                }
            }else{
                System.out.println("普通商品订单号：" + out_trade_no + "不存在");
                logger.error("普通商品订单号：" + out_trade_no + "不存在");
            }
        }catch (Exception ex){
            ex.printStackTrace();
            System.out.println(""+ex.getMessage());
        }
        return ret;
    }

    /**
     * 商品订单的 退款成功处理
     * @param params
     * @return
     */
    @SuppressWarnings("unchecked")
    private int refund_success_product(Map<String, String> params,int payType){
        String out_trade_no = params.get("out_trade_no");// 本平台  商户订单号
        if(payType == 2){
            out_trade_no = params.get("merOrderId");// 本平台  商户订单号
        }
        System.out.println("商品退款订单的订单号：" + out_trade_no + "，退款回调");
        int ret = 0;
        try{
            QueryWrapper<ProductOrder> qw = new QueryWrapper<>();
            qw.eq("out_trade_no",out_trade_no).or().eq("order_no",out_trade_no);
            ProductOrder order = productOrderService.getOne(qw);
            if(order != null){
                User user = userService.findById(order.getUserId());
                if(order.getStatus() == 7) {//发起退款 并同意申请 的才执行
                    String refund_fee = "";//  订单金额
                    String trade_no = "";//  订单号
                    double refund_fee_double = 0;

//                    refund_fee = params.get("refund_fee");
//                    trade_no = params.get("transaction_id");//微信支付订单号
//                    refund_fee_double = Double.valueOf(refund_fee) / 100;

                    if (payType == 0) {//支付宝支付参数
                        refund_fee = params.get("refund_fee");
                        trade_no = params.get("transaction_id");//微信支付订单号
                        refund_fee_double = Double.valueOf(refund_fee) / 100;
                    } else if (payType == 1) {//微信支付参数
                        refund_fee = params.get("refund_fee");
                        trade_no = params.get("transaction_id");//微信支付订单号
                        refund_fee_double = Double.valueOf(refund_fee) / 100;
                    } else if (payType == 2) {// 农商行 支付参数
                        refund_fee = params.get("refundAmount");
                        refund_fee_double = Double.valueOf(refund_fee) / 100;
                        trade_no = params.get("targetOrderId");//微信支付订单号
                    }


                    //订单状态 0 - 未支付   1 - 支付中  2 - 已支付（待核销）  3 - 已核销
                    // 4 - 已评价  5 - 订单取消  6 - 发起退货  7 - 同意退货  8 - 退货完成  9 - 拒绝退货
                    order.setStatus(8);
                    order.setTransactionId(trade_no);
                    order.setRefundStatus(2);
                    order.setRefundPrice(new BigDecimal(refund_fee_double));
                    order.setRefundReasonTime(new Date());
                    ret = productOrderService.buyNormalUpdate(order,user);
                    if(ret > 0){
                        //退款成功通知
                        sendWxMsgRefund(user,order,4);
                    }

                    // 添加 微信支付的 动账记录
                    WxPayTransaction transaction = new WxPayTransaction();
                    transaction.setPayType(payType);// 0 -微信支付
                    transaction.setTransactionId(trade_no);
                    transaction.setUserId(user.getId());
                    transaction.setFeeType("product_refund");
                    transaction.setTotalMoney(new BigDecimal(refund_fee_double));
                    transaction.setOutTradeNo(order.getOutTradeNo());
                    if(StrUtil.isNotEmpty(user.getNickName())){
                        transaction.setNickName(EmojiParser.parseToAliases(user.getNickName()));
                    }
                    transaction.setCreateTime(new Date());
                    transaction.setInOrOut(0);//动账  0 - 出账 1 - 进账
                    transaction.setRemark("购买商品/服务的退款");
                    transaction.setPayPlatformId(order.getPayPlatformId());
                    payTransactionService.save(transaction);
                    System.out.println("=====退款成功====");
                    logger.info("普通商品订单号：" + out_trade_no + "退款成功");
                }
            }else{
                System.out.println("普通商品订单号：" + out_trade_no + "不存在");
                logger.error("普通商品订单号：" + out_trade_no + "不存在");
            }
        }catch (Exception ex){
            ex.printStackTrace();
            System.out.println(ex.getMessage());
        }
        return ret;
    }

    /**
     *  订单支付成功 公众号推送消息
     * @param user
     * @param order
     * @param template_type
     * @return
     */
    public int sendWxMsg(User user, ProductOrder order, Integer template_type){
        try{
            List<UserMp> userMps = userMpService.selectUserMpList(order.getMerId());
            String access_token = wxTemplateService.getAccessToken(0);
            if(CollUtil.isNotEmpty(userMps)){
                for(UserMp userMp : userMps){
                    WxMsgTemplate template = null;
                    if(template_type == 7){//支付成功发送推送消息到 商家管理员微信上
                        template = getTemplateToMerManager(userMp,order,template_type);
                    }
                    String param = JSONUtil.parseObj(template).toString();
                    JSONObject jsonObject = WxMessage.sendMsg(access_token,param);
                    System.out.println("公众号推送消息 - 商家端响应信息:" + jsonObject.toString());
                }
            }
            WxMsgTemplate template = getTemplateToUser(user,order,3);
            String param = JSONUtil.parseObj(template).toString();
            JSONObject jsonObject = WxMessage.sendMsg(access_token,param);
            System.out.println("公众号推送消息 - 用户端响应信息:" + jsonObject.toString());

        }catch (Exception e){
            e.printStackTrace();
            logger.error(e.getMessage(), e);
            System.out.println("发送失败" + e.getMessage());
        }
        return 1;
    }

    /**
     *  普通订单退款成功 公众号推送消息
     * @param user
     * @param order
     * @param template_type
     * @return
     */
    public int sendWxMsgRefund(User user, ProductOrder order, Integer template_type){
        try{
            if(order != null){
//                String accessToken = WxMessage.getACCESSTOKEN(appidMp,secretMp);
//                String access_token = redisTemplate.opsForValue().get("access_token_mp")!=null ? redisTemplate.opsForValue().get("access_token_mp").toString() : null;
//                if(StrUtil.isEmpty(access_token)){
//                    access_token = WxMessage.getACCESSTOKEN(appidMp,secretMp);
//                    redisTemplate.opsForValue().set("access_token_mp",access_token,3600L, TimeUnit.SECONDS);
//                }
                String access_token = wxTemplateService.getAccessToken(0);// WxMessage.getACCESSTOKEN(appidMp,secretMp);

                //给用户发送支付成功消息
                WxMsgTemplate template = getTemplateToUserByRefund(user,order,template_type);
                String param = JSONUtil.parseObj(template).toString();
                JSONObject jsonObject = WxMessage.sendMsg(access_token,param);
                System.out.println("公众号推送消息 - 用户端响应信息:" + jsonObject.toString());
            }
        }catch (Exception e){
            e.printStackTrace();
            logger.error(e.getMessage(), e);
            System.out.println("发送失败" + e.getMessage());
        }
        return 1;
    }

    /**
     *  发送推送消息到 商家管理员微信上
     * @param user
     * @param order
     * @param template_type
     * @return
     */
    private WxMsgTemplate getTemplateToUser(User user, ProductOrder order, Integer template_type){
        WxMsgTemplate template = new WxMsgTemplate();
        WxTemplate wxTemplate = wxTemplateService.selectByUniqueColumn("template_type",template_type);
        QueryWrapper<UserMp> qw = new QueryWrapper<>();
        qw.eq("platform", user.getPlatform());
        qw.eq("union_id",user.getUnionId());
        qw.last("limit 1");
        UserMp userMp = userMpService.getOne(qw);
        if(userMp != null){
            template.setTouser(userMp.getOpenId());
            template.setTemplate_id(wxTemplate.getTemplateId());
            template.setUrl("");

            Map<String,Object> miniprogram = new HashMap<>();
            miniprogram.put("appid",appid);
            miniprogram.put("pagepath","pages/order/productList/index?state=0");
            template.setMiniprogram(miniprogram);

            Map<String, MsgTempData> m = new HashMap<String, MsgTempData>();
            //您好，您的订单支付成功！
            //订单号：JPH81
            //支付金额：200元
            //支付时间：2016-04-01 12:32
            //感谢您的使用
            MsgTempData first = new MsgTempData();
            first.setColor(wxTemplate.getFontColor());
            first.setValue("尊敬的用户您好，您的订单支付成功！");
            m.put("first",first);

            //订单号
            MsgTempData keyword1 = new MsgTempData();
            keyword1.setColor(wxTemplate.getFontColor());
            keyword1.setValue(order.getOrderNo());
            m.put("keyword1",keyword1);

            //支付金额
            MsgTempData keyword2 = new MsgTempData();
            keyword2.setColor(wxTemplate.getFontColor());
            keyword2.setValue(MathUtil.getDoubleUp(order.getPayPrice().doubleValue()) + "元");
            m.put("keyword2",keyword2);

            //支付时间
            MsgTempData keyword3 = new MsgTempData();
            keyword3.setColor(wxTemplate.getFontColor());
            keyword3.setValue(DateUtil.getTime(order.getPayTime()));
            m.put("keyword3",keyword3);

            MsgTempData remark = new MsgTempData();
            remark.setColor(wxTemplate.getFontColor());
            remark.setValue("感谢您的使用");
            m.put("remark",remark);

            template.setData(m);
        }
        return template;
    }

    /**
     *  发送推送消息到 商家管理员微信上
     * @param user
     * @param order
     * @param template_type
     * @return
     */
    private WxMsgTemplate getTemplateToUserByRefund(User user, ProductOrder order, Integer template_type){
        WxMsgTemplate template = new WxMsgTemplate();
        WxTemplate wxTemplate = wxTemplateService.selectByUniqueColumn("template_type",template_type);
        QueryWrapper<UserMp> qw = new QueryWrapper<>();
        qw.eq("platform", user.getPlatform());
        qw.eq("union_id",user.getUnionId());
        qw.last("limit 1");
        UserMp userMp = userMpService.getOne(qw);
        if(userMp != null){
            template.setTouser(userMp.getOpenId());
            template.setTemplate_id(wxTemplate.getTemplateId());
            template.setUrl("");

            Map<String,Object> miniprogram = new HashMap<>();
            miniprogram.put("appid",appid);
            miniprogram.put("pagepath","pages/order/productList/index?index=0");
            template.setMiniprogram(miniprogram);

            Map<String, MsgTempData> m = new HashMap<String, MsgTempData>();
//            {{first.DATA}}
//            订单号：{{keyword1.DATA}}
//            商品：{{keyword2.DATA}}
//            退款金额：{{keyword3.DATA}}
//            客户名称：{{keyword4.DATA}}
//            退款原因：{{keyword5.DATA}}
//            {{remark.DATA}}
            MsgTempData first = new MsgTempData();
            first.setColor(wxTemplate.getFontColor());
            if(order.getOrderType() == 4){
                first.setValue("尊敬的用户您好，您的拼团未成团，订单已退款！");
            }else{
                first.setValue("尊敬的用户您好，您的订单已退款完成！");
            }
            m.put("first",first);

            //订单号
            MsgTempData keyword1 = new MsgTempData();
            keyword1.setColor(wxTemplate.getFontColor());
            keyword1.setValue(order.getOrderNo());
            m.put("keyword1",keyword1);

            //商品
            MsgTempData keyword2 = new MsgTempData();
            keyword2.setColor(wxTemplate.getFontColor());
            Product product = productService.getProductByOrderId(order.getId());
            if(product!=null){
                keyword2.setValue(product.getStoreName());
            }else{
                keyword2.setValue("");
            }
            m.put("keyword2",keyword2);

            //客户名称
            MsgTempData keyword3 = new MsgTempData();
            keyword3.setColor(wxTemplate.getFontColor());
            keyword3.setValue(EmojiParser.parseToUnicode(user.getNickName()));
            m.put("keyword3",keyword3);

            //退款金额
            MsgTempData keyword4 = new MsgTempData();
            keyword4.setColor(wxTemplate.getFontColor());
            keyword4.setValue(MathUtil.getDoubleUp(order.getRefundPrice().doubleValue())+"");
            m.put("keyword4",keyword4);

            //备注信息
            MsgTempData remark = new MsgTempData();
            remark.setColor(wxTemplate.getFontColor());
            remark.setValue("感谢您的使用,退款金额以到账为准");
            m.put("remark",remark);

            template.setData(m);
        }
        return template;
    }

    /**
     *  发送推送消息到 商家管理员微信上
     * @param userMp
     * @param order
     * @param template_type
     * @return
     */
    private WxMsgTemplate getTemplateToMerManager(UserMp userMp, ProductOrder order, Integer template_type){
        WxMsgTemplate template = new WxMsgTemplate();
        WxTemplate wxTemplate = wxTemplateService.selectByUniqueColumn("template_type",template_type);
        if(userMp != null){
            template.setTouser(userMp.getOpenId());
            template.setTemplate_id(wxTemplate.getTemplateId());
            template.setUrl("");

            Map<String,Object> miniprogram = new HashMap<>();
            miniprogram.put("appid",appid);
            miniprogram.put("pagepath","pagesMer/pages/orderList/index?state=0");
            template.setMiniprogram(miniprogram);

            Map<String, MsgTempData> m = new HashMap<String, MsgTempData>();
//            有客户要看房啦，请及时处理
//            提交时间：2018-07-09
//            订单类型：看房
//            客户信息：张丽 电话：1111111111111
//            房屋信息：杭州市西湖区湖墅南路111号
//            感谢您的使用。
            MsgTempData first = new MsgTempData();
            first.setColor(wxTemplate.getFontColor());
            first.setValue("尊敬的商家用户您好，您有新客户订单");
            m.put("first",first);

            //提交时间
            MsgTempData keyword1 = new MsgTempData();
            keyword1.setColor(wxTemplate.getFontColor());
            keyword1.setValue(DateUtil.getSdfTimesCN());
            m.put("keyword1",keyword1);

            //订单类型
            MsgTempData keyword2 = new MsgTempData();
            keyword2.setColor(wxTemplate.getFontColor());
            keyword2.setValue("商家服务");
            m.put("keyword2",keyword2);

            //客户信息
            MsgTempData keyword3 = new MsgTempData();
            keyword3.setColor(wxTemplate.getFontColor());
            keyword3.setValue(order.getRealName() + "(" + order.getUserPhone()+")");
            m.put("keyword3",keyword3);

            //房屋信息
            MsgTempData keyword4 = new MsgTempData();
            keyword4.setColor(wxTemplate.getFontColor());
            keyword4.setValue(order.getUserAddress());
            m.put("keyword4",keyword4);

            MsgTempData remark = new MsgTempData();
            remark.setColor(wxTemplate.getFontColor());
            remark.setValue("客户已下单，请及时跟进处理");
            m.put("remark",remark);

            template.setData(m);
        }
        return template;
    }

}
